package com.ai.imagetext.controller;

import com.ai.imagetext.dto.ImageDTO;
import com.ai.imagetext.dto.SimpleResponse;
import com.ai.imagetext.dto.TagDTO;
import com.ai.imagetext.repository.ImageRepository;
import com.ai.imagetext.service.SearchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.data.domain.Page;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/search")
@RequiredArgsConstructor
public class SearchController {
    
    private final SearchService searchService;
    private final ImageRepository imageRepository;

    @PostMapping("/fuzzy")
    public ResponseEntity<Map<String, Object>> fuzzySearch(@RequestParam String keyword,
                                                           @RequestParam(defaultValue = "0") int page,
                                                           @RequestParam(defaultValue = "20") int size,
                                                           @RequestParam(defaultValue = "createdAt") String sortBy,
                                                           @RequestParam(defaultValue = "desc") String sortDir) {
        log.info("fuzzy search request with criteria: {}", keyword);

        try {
            Page<ImageDTO> imagePage = searchService.fuzzySearch(keyword,  page,  size,  sortBy,  sortDir);

            Map<String, Object> response = createSuccessResponse("高级搜索完成");
            response.put("data", imagePage.getContent());
            response.put("pagination", createPaginationInfo(imagePage));

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Advanced search failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }



    /**
     * 高级搜索
     */
    @PostMapping("/advanced")
    public ResponseEntity<Map<String, Object>> advancedSearch(@RequestBody SearchService.SearchCriteria criteria) {
        log.info("Advanced search request with criteria: {}", criteria);
        
        try {
            Page<ImageDTO> imagePage = searchService.advancedSearchImages(criteria);
            
            Map<String, Object> response = createSuccessResponse("高级搜索完成");
            response.put("data", imagePage.getContent());
            response.put("pagination", createPaginationInfo(imagePage));
            response.put("criteria", criteria);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Advanced search failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 根据图片ID数组批量获取图片URL - 完全避免DTO序列化
     */
    @PostMapping("/batch-urls")
    public List<String> getImageUrlsByIds(@RequestBody List<Object> imageIds) {
        log.info("Batch get images by IDs: {}", imageIds);

        try {
            if (imageIds == null || imageIds.isEmpty()) {
                return new ArrayList<String>();
            }

            // 转换为Long类型
            List<Long> longIds = new ArrayList<>();
            for (Object id : imageIds) {
                try {
                    if (id instanceof Integer) {
                        longIds.add(((Integer) id).longValue());
                    } else if (id instanceof Long) {
                        longIds.add((Long) id);
                    } else if (id instanceof String) {
                        longIds.add(Long.parseLong((String) id));
                    } else {
                        log.warn("Invalid ID type: {}, skipping", id.getClass().getSimpleName());
                    }
                } catch (NumberFormatException e) {
                    log.warn("Failed to parse ID: {}, skipping", id);
                }
            }

            log.info("Processing IDs: {}", longIds);

            // 直接从数据库获取URL，避免DTO序列化
            List<String> imageUrls = getImageUrlsDirectly(longIds);

            log.info("Found {} image URLs", imageUrls.size());

            return imageUrls;

        } catch (Exception e) {
            log.error("Batch get images by IDs failed", e);
            return new ArrayList<String>();
        }
    }

    /**
     * 直接从数据库获取图片URL，避免DTO序列化问题
     */
    private List<String> getImageUrlsDirectly(List<Long> imageIds) {
        if (imageIds == null || imageIds.isEmpty()) {
            return new ArrayList<>();
        }

        try {
            // 直接查询数据库获取URL
            List<String> urls = new ArrayList<>();
            for (Long id : imageIds) {
                String url = imageRepository.findById(id)
                    .filter(image -> !image.getIsDeleted())
                    .map(image -> image.getFileUrl())
                    .orElse(null);
                if (url != null) {
                    urls.add(url);
                }
            }
            return urls;
        } catch (Exception e) {
            log.error("Error getting image URLs directly", e);
            return new ArrayList<>();
        }
    }




    /**
     * 多标签筛选
     */
    @GetMapping("/tags")
    public ResponseEntity<Map<String, Object>> filterByTags(
            @RequestParam List<String> tags,
            @RequestParam(defaultValue = "AND") String logic,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "createdAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        
        log.info("Filter by tags: {}, logic: {}, userId: {}", tags, logic);
        
        try {
            Page<ImageDTO> imagePage = searchService.filterImagesByTags(tags, logic, page, size, sortBy, sortDir);
            
            Map<String, Object> response = createSuccessResponse("标签筛选完成");
            response.put("data", imagePage.getContent());
            response.put("pagination", createPaginationInfo(imagePage));
            response.put("tags", tags);
            response.put("logic", logic);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Filter by tags failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 获取热门标签
     */
    @GetMapping("/popular-tags")
    public ResponseEntity<Map<String, Object>> getPopularTags(@RequestParam(defaultValue = "20") int limit) {
        log.info("Getting popular tags with limit: {}", limit);
        
        try {
            List<SearchService.TagStatistics> popularTags = searchService.getPopularTags(limit);
            
            Map<String, Object> response = createSuccessResponse("获取热门标签成功");
            response.put("data", popularTags);
            response.put("limit", limit);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get popular tags failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 获取标签云
     */
    @GetMapping("/tag-cloud")
    public ResponseEntity<Map<String, Object>> getTagCloud(@RequestParam(defaultValue = "50") int maxTags) {
        log.info("Getting tag cloud with max tags: {}", maxTags);
        
        try {
            List<SearchService.TagCloudItem> tagCloud = searchService.getTagCloud(maxTags);
            
            Map<String, Object> response = createSuccessResponse("获取标签云成功");
            response.put("data", tagCloud);
            response.put("maxTags", maxTags);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get tag cloud failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 按分类获取标签
     */
    @GetMapping("/tags-by-category")
    public ResponseEntity<Map<String, Object>> getTagsByCategory() {
        log.info("Getting tags grouped by category");
        
        try {
            Map<String, List<TagDTO>> tagsByCategory = searchService.getTagsByCategory();
            
            Map<String, Object> response = createSuccessResponse("获取分类标签成功");
            response.put("data", tagsByCategory);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get tags by category failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 搜索建议（自动完成）
     */
    @GetMapping("/suggestions")
    public ResponseEntity<Map<String, Object>> getSearchSuggestions(
            @RequestParam String query,
            @RequestParam(defaultValue = "10") int limit) {
        
        log.info("Getting search suggestions for query: {}", query);
        
        try {
            List<SearchService.SearchSuggestion> suggestions = searchService.getSearchSuggestions(query, limit);
            
            Map<String, Object> response = createSuccessResponse("获取搜索建议成功");
            response.put("data", suggestions);
            response.put("query", query);
            response.put("limit", limit);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get search suggestions failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 获取相关标签
     */
    @GetMapping("/related-tags")
    public ResponseEntity<Map<String, Object>> getRelatedTags(
            @RequestParam String tagName,
            @RequestParam(defaultValue = "10") int limit) {
        
        log.info("Getting related tags for: {}", tagName);
        
        try {
            List<String> relatedTags = searchService.getRelatedTags(tagName, limit);
            
            Map<String, Object> response = createSuccessResponse("获取相关标签成功");
            response.put("data", relatedTags);
            response.put("tagName", tagName);
            response.put("limit", limit);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get related tags failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 快速搜索（简化版）
     */
    @GetMapping("/quick")
    public ResponseEntity<Map<String, Object>> quickSearch(
            @RequestParam String keyword,
            @RequestParam(required = false) List<String> tags,
            @RequestParam(required = false) List<String> mimeTypes,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        log.info("Quick search: keyword={}, tags={}, mimeTypes={}", keyword, tags, mimeTypes);
        
        try {
            SearchService.SearchCriteria criteria = new SearchService.SearchCriteria();
            criteria.setKeyword(keyword);
            criteria.setTags(tags);
            criteria.setMimeTypes(mimeTypes);
            criteria.setPage(page);
            criteria.setSize(size);
            
            Page<ImageDTO> imagePage = searchService.advancedSearchImages(criteria);
            
            Map<String, Object> response = createSuccessResponse("快速搜索完成");
            response.put("data", imagePage.getContent());
            response.put("pagination", createPaginationInfo(imagePage));
            response.put("keyword", keyword);
            response.put("tags", tags);
            response.put("mimeTypes", mimeTypes);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Quick search failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 按时间范围搜索
     */
    @GetMapping("/date-range")
    public ResponseEntity<Map<String, Object>> searchByDateRange(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")  LocalDateTime startDate,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")  LocalDateTime endDate,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) List<String> tags,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        log.info("Search by date range: {} to {}", startDate, endDate);
        
        try {
            SearchService.SearchCriteria criteria = new SearchService.SearchCriteria();
            criteria.setStartDate(startDate);
            criteria.setEndDate(endDate);
            criteria.setKeyword(keyword);
            criteria.setTags(tags);
            criteria.setPage(page);
            criteria.setSize(size);
            
            Page<ImageDTO> imagePage = searchService.advancedSearchImages(criteria);
            
            Map<String, Object> response = createSuccessResponse("时间范围搜索完成");
            response.put("data", imagePage.getContent());
            response.put("pagination", createPaginationInfo(imagePage));
            response.put("startDate", startDate);
            response.put("endDate", endDate);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Search by date range failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 按文件大小范围搜索
     */
    @GetMapping("/file-size-range")
    public ResponseEntity<Map<String, Object>> searchByFileSizeRange(
            @RequestParam(required = false) Long minSize,
            @RequestParam(required = false) Long maxSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) List<String> tags,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        log.info("Search by file size range: {} to {}", minSize, maxSize);
        
        try {
            SearchService.SearchCriteria criteria = new SearchService.SearchCriteria();
            criteria.setMinFileSize(minSize);
            criteria.setMaxFileSize(maxSize);
            criteria.setKeyword(keyword);
            criteria.setTags(tags);
            criteria.setPage(page);
            criteria.setSize(size);
            
            Page<ImageDTO> imagePage = searchService.advancedSearchImages(criteria);
            
            Map<String, Object> response = createSuccessResponse("文件大小范围搜索完成");
            response.put("data", imagePage.getContent());
            response.put("pagination", createPaginationInfo(imagePage));
            response.put("minSize", minSize);
            response.put("maxSize", maxSize);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Search by file size range failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 智能关键词搜索
     */
    @GetMapping("/intelligent")
    public ResponseEntity<Map<String, Object>> intelligentKeywordSearch(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "relevance") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        
        log.info("Intelligent keyword search: {}", keyword);
        
        try {
            SearchService.SearchResult result = searchService.smartKeywordSearch(keyword, page, size, sortBy, sortDir);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", result.isSuccess());
            response.put("message", result.getMessage());
            response.put("keyword", result.getKeyword());
            response.put("data", result.getImages());
            response.put("totalResults", result.getTotalResults());
            response.put("currentPage", result.getCurrentPage());
            response.put("totalPages", result.getTotalPages());
            response.put("pageSize", result.getPageSize());
            response.put("hasNext", result.isHasNext());
            response.put("hasPrevious", result.isHasPrevious());
            response.put("suggestions", result.getSuggestions());
            response.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Intelligent keyword search failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 获取热门搜索词
     */
    @GetMapping("/hot-keywords")
    public ResponseEntity<Map<String, Object>> getHotSearchKeywords(@RequestParam(defaultValue = "10") int limit) {
        log.info("Getting hot search keywords with limit: {}", limit);
        
        try {
            List<String> hotKeywords = searchService.getHotSearchKeywords(limit);
            
            Map<String, Object> response = createSuccessResponse("获取热门搜索词成功");
            response.put("data", hotKeywords);
            response.put("limit", limit);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get hot search keywords failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 记录搜索历史
     */
    @PostMapping("/history")
    public ResponseEntity<Map<String, Object>> recordSearchHistory(@RequestBody Map<String, String> request) {
        String keyword = request.get("keyword");
        String userId = request.get("userId");
        
        log.info("Recording search history: keyword={}, userId={}", keyword, userId);
        
        try {
            searchService.recordSearchHistory(keyword, userId);
            
            Map<String, Object> response = createSuccessResponse("搜索历史记录成功");
            response.put("keyword", keyword);
            response.put("userId", userId);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Record search history failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 搜索统计信息
     */
    @GetMapping("/statistics")
    public ResponseEntity<Map<String, Object>> getSearchStatistics() {
        log.info("Getting search statistics");
        
        try {
            Map<String, Object> statistics = new HashMap<>();
            
            // 获取热门标签
            List<SearchService.TagStatistics> popularTags = searchService.getPopularTags(10);
            statistics.put("popularTags", popularTags);
            
            // 获取热门搜索词
            List<String> hotKeywords = searchService.getHotSearchKeywords(10);
            statistics.put("hotKeywords", hotKeywords);
            
            // 获取标签分类统计
            Map<String, List<TagDTO>> tagsByCategory = searchService.getTagsByCategory();
            Map<String, Integer> categoryStats = new HashMap<>();
            tagsByCategory.forEach((category, tags) -> categoryStats.put(category, tags.size()));
            statistics.put("categoryStats", categoryStats);
            
            Map<String, Object> response = createSuccessResponse("获取搜索统计信息成功");
            response.put("data", statistics);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Get search statistics failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }
    
    /**
     * 创建分页信息
     */
    private Map<String, Object> createPaginationInfo(Page<?> page) {
        Map<String, Object> pagination = new HashMap<>();
        pagination.put("currentPage", page.getNumber());
        pagination.put("totalPages", page.getTotalPages());
        pagination.put("totalElements", page.getTotalElements());
        pagination.put("size", page.getSize());
        pagination.put("hasNext", page.hasNext());
        pagination.put("hasPrevious", page.hasPrevious());
        return pagination;
    }
    
    /**
     * 创建成功响应
     */
    private Map<String, Object> createSuccessResponse(String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", message);
        response.put("timestamp", System.currentTimeMillis());
        return response;
    }
    
    /**
     * 创建错误响应
     */
    private Map<String, Object> createErrorResponse(String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("success", false);
        response.put("message", message);
        response.put("timestamp", System.currentTimeMillis());
        return response;
    }
}